package br.com.intelsys.basics.utils;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

import java.awt.image.BufferedImage;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import br.com.intelsys.basics.utils.IPicture.IPictureSize;

public class IPictureTest {
	private static final int FROM_LANDSCAPE_WIDTH = 200;
	private static final int FROM_LANDSCAPE_HEIGHT = 100;
	private static final int FROM_LANDSCAPE_WIDTH_LOWER = FROM_LANDSCAPE_WIDTH / 2;
	private static final int FROM_LANDSCAPE_HEIGHT_LOWER = FROM_LANDSCAPE_HEIGHT / 2;
	private static final int FROM_LANDSCAPE_WIDTH_BIGGER = FROM_LANDSCAPE_WIDTH * 2;
	private static final int FROM_LANDSCAPE_HEIGHT_BIGGER = FROM_LANDSCAPE_HEIGHT * 2;

	private static final int FROM_PORTRAIT_WIDTH = 100;
	private static final int FROM_PORTRAIT_HEIGHT = 200;
	private static final int FROM_PORTRAIT_WIDTH_LOWER = FROM_PORTRAIT_WIDTH / 2;
	private static final int FROM_PORTRAIT_HEIGHT_LOWER = FROM_PORTRAIT_HEIGHT / 2;
	private static final int FROM_PORTRAIT_WIDTH_BIGGER = FROM_PORTRAIT_WIDTH * 2;
	private static final int FROM_PORTRAIT_HEIGHT_BIGGER = FROM_PORTRAIT_HEIGHT * 2;

	private static final int FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER = FROM_LANDSCAPE_WIDTH / 2;
	private static final int FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER_RESULT_WIDTH = FROM_LANDSCAPE_WIDTH / 2;
	private static final int FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER_RESULT_HEIGHT = FROM_LANDSCAPE_HEIGHT / 2;

	private static final int FROM_LANDSCAPE_FIT_TO_SQUARE_BIGGER = FROM_LANDSCAPE_WIDTH * 2;

	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_WIDTH = FROM_LANDSCAPE_WIDTH / 2;
	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_HEIGHT = FROM_LANDSCAPE_HEIGHT * 2;
	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_HEIGHT_RESULT = FROM_LANDSCAPE_HEIGHT / 2;

	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_WIDTH = FROM_LANDSCAPE_WIDTH * 2;
	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_HEIGHT = FROM_LANDSCAPE_HEIGHT / 2;
	private static final int FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_WIDTH_RESULT = FROM_LANDSCAPE_WIDTH / 2;

	private static final int FROM_PORTRAIT_FIT_TO_SQUARE_LOWER = FROM_PORTRAIT_HEIGHT / 2;
	private static final int FROM_PORTRAIT_FIT_TO_SQUARE_LOWER_RESULT_WIDTH = FROM_PORTRAIT_WIDTH / 2;
	private static final int FROM_PORTRAIT_FIT_TO_SQUARE_LOWER_RESULT_HEIGHT = FROM_PORTRAIT_HEIGHT / 2;

	private static final int FROM_PORTRAIT_FIT_TO_SQUARE_BIGGER = FROM_PORTRAIT_HEIGHT * 2;

	private static final int FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_WIDTH = FROM_PORTRAIT_WIDTH / 2;
	private static final int FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_HEIGHT = FROM_PORTRAIT_HEIGHT * 2;
	private static final int FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_HEIGHT_RESULT = FROM_PORTRAIT_HEIGHT / 2;

	private static final int FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_WIDTH = FROM_PORTRAIT_WIDTH * 2;
	private static final int FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_HEIGHT = FROM_PORTRAIT_HEIGHT / 2;
	private static final int FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_WIDTH_RESULT = FROM_PORTRAIT_WIDTH / 2;

	@Mock
	private BufferedImage bsrc;

	@Before
	public void setUp() throws Exception {
		MockitoAnnotations.initMocks(this);
	}

	@Test
	public void resizeLandscapeFromLowerWidth() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_LANDSCAPE_WIDTH, FROM_LANDSCAPE_HEIGHT, FROM_LANDSCAPE_WIDTH_LOWER, true) == FROM_LANDSCAPE_HEIGHT_LOWER);
	}

	@Test
	public void resizeLandscapeFromLowerHeight() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_LANDSCAPE_WIDTH, FROM_LANDSCAPE_HEIGHT, FROM_LANDSCAPE_HEIGHT_LOWER, false) == FROM_LANDSCAPE_WIDTH_LOWER);
	}

	@Test
	public void resizeLandscapeFromBiggerWidth() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_LANDSCAPE_WIDTH, FROM_LANDSCAPE_HEIGHT, FROM_LANDSCAPE_WIDTH_BIGGER, true) == IPicture.IPICTURE_BIGGER_ERROR);
	}

	@Test
	public void resizeLandscapeFromBiggerHeight() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_LANDSCAPE_WIDTH, FROM_LANDSCAPE_HEIGHT, FROM_LANDSCAPE_HEIGHT_BIGGER, false) == IPicture.IPICTURE_BIGGER_ERROR);
	}

	@Test
	public void resizePortraitFromLowerWidth() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_PORTRAIT_WIDTH, FROM_PORTRAIT_HEIGHT, FROM_PORTRAIT_WIDTH_LOWER, true) == FROM_PORTRAIT_HEIGHT_LOWER);
	}

	@Test
	public void resizePortraitFromLowerHeight() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_PORTRAIT_WIDTH, FROM_PORTRAIT_HEIGHT, FROM_PORTRAIT_HEIGHT_LOWER, false) == FROM_PORTRAIT_WIDTH_LOWER);
	}

	@Test
	public void resizePortraitFromBiggerWidth() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_PORTRAIT_WIDTH, FROM_PORTRAIT_HEIGHT, FROM_PORTRAIT_WIDTH_BIGGER, true) == IPicture.IPICTURE_BIGGER_ERROR);
	}

	@Test
	public void resizePortraitFromBiggerHeight() throws Exception {
		assertTrue(IPicture.calcPropResize(FROM_PORTRAIT_WIDTH, FROM_PORTRAIT_HEIGHT, FROM_PORTRAIT_HEIGHT_BIGGER, false) == IPicture.IPICTURE_BIGGER_ERROR);
	}

	private void prepareLandscape() {
		when(bsrc.getWidth()).thenReturn(FROM_LANDSCAPE_WIDTH);
		when(bsrc.getHeight()).thenReturn(FROM_LANDSCAPE_HEIGHT);

	}

	@Test
	public void fitLandscapeToSquareLower() throws Exception {
		prepareLandscape();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER, FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER);
		assertNotNull(ipSize);
		assertTrue(ipSize.getWidth() == FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER_RESULT_WIDTH);
		assertTrue(ipSize.getHeight() == FROM_LANDSCAPE_FIT_TO_SQUARE_LOWER_RESULT_HEIGHT);
	}

	@Test
	public void fitLandscapeToSquareBigger() throws Exception {
		prepareLandscape();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_LANDSCAPE_FIT_TO_SQUARE_BIGGER, FROM_LANDSCAPE_FIT_TO_SQUARE_BIGGER);
		assertNull(ipSize);
	}

	@Test
	public void fitLandscapeToLowerPortrait() throws Exception {
		prepareLandscape();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_WIDTH, FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_HEIGHT);
		assertTrue(ipSize.getWidth() == FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_WIDTH);
		assertTrue(ipSize.getHeight() == FROM_LANDSCAPE_FIT_TO_LOWER_PORTRAIT_HEIGHT_RESULT);
	}

	@Test
	public void fitLandscapeToLowerLandscape() throws Exception {
		prepareLandscape();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip
				.fitScaleTo(bsrc, FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_WIDTH, FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_HEIGHT);
		assertTrue(ipSize.getWidth() == FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_WIDTH_RESULT);
		assertTrue(ipSize.getHeight() == FROM_LANDSCAPE_FIT_TO_LOWER_LANDSCAPE_HEIGHT);
	}

	private void preparePortrait() {
		when(bsrc.getWidth()).thenReturn(FROM_PORTRAIT_WIDTH);
		when(bsrc.getHeight()).thenReturn(FROM_PORTRAIT_HEIGHT);

	}

	@Test
	public void fitPortraitToSquareLower() throws Exception {
		preparePortrait();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_PORTRAIT_FIT_TO_SQUARE_LOWER, FROM_PORTRAIT_FIT_TO_SQUARE_LOWER);
		assertNotNull(ipSize);
		assertTrue(ipSize.getWidth() == FROM_PORTRAIT_FIT_TO_SQUARE_LOWER_RESULT_WIDTH);
		assertTrue(ipSize.getHeight() == FROM_PORTRAIT_FIT_TO_SQUARE_LOWER_RESULT_HEIGHT);
	}

	@Test
	public void fitPortraitToSquareBigger() throws Exception {
		preparePortrait();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_PORTRAIT_FIT_TO_SQUARE_BIGGER, FROM_PORTRAIT_FIT_TO_SQUARE_BIGGER);
		assertNull(ipSize);
	}

	@Test
	public void fitPortraitToLowerPortrait() throws Exception {
		preparePortrait();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_WIDTH, FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_HEIGHT);
		assertTrue(ipSize.getWidth() == FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_WIDTH);
		assertTrue(ipSize.getHeight() == FROM_PORTRAIT_FIT_TO_LOWER_PORTRAIT_HEIGHT_RESULT);
	}

	@Test
	public void fitPortraitToLowerLandscape() throws Exception {
		preparePortrait();
		IPicture ip = new IPicture();
		IPictureSize ipSize = ip.fitScaleTo(bsrc, FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_WIDTH, FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_HEIGHT);
		assertTrue(ipSize.getWidth() == FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_WIDTH_RESULT);
		assertTrue(ipSize.getHeight() == FROM_PORTRAIT_FIT_TO_LOWER_LANDSCAPE_HEIGHT);
	}
}
